package com.my.app.controller;

import com.my.app.http.HttpResult;
import com.my.sys.model.SysUser;
import com.my.utils.CommonUtils;
import com.my.utils.Constants;
import com.my.utils.TokenUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.util.SavedRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.my.sys.service.SysUserService;

@RestController
public class LoginController {

    private final Logger logger = LogManager.getLogger(getClass());

    @Autowired
    private SysUserService sysUserService;

    @RequestMapping(value = "login", method = RequestMethod.GET)
    public ModelAndView loginPage(Model model) {
        logger.info("Go login ...");
        model.addAttribute("url", "login");
        return new ModelAndView("login");
    }

    @RequestMapping(value = "login", method = RequestMethod.POST)
    public HttpResult<SysUser> login(@RequestParam("username") String username,
                                     @RequestParam("password") String password, @RequestParam(required = false) boolean remember) {

        HttpResult<SysUser> result = new HttpResult<SysUser>();
        logger.debug("To login username[{}], password[{}], remember[{}]", username, password, remember);

        String view = "login";
        String msg = "";

        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        token.setRememberMe(remember);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
            if (subject.isAuthenticated()) {
                Session session = subject.getSession(false);
                if (session != null) {
                    SavedRequest savedRequest = (SavedRequest) session.getAttribute(Constants.SAVED_REQUEST_KEY);
                    if (savedRequest == null || savedRequest.getRequestUrl() == null) {
                        view = "redirect:/dashboard";
                    } else {
                        String url = savedRequest.getRequestUrl();
                        url = url.substring(url.indexOf("/", 2));
                        logger.debug("request url:{}", url);
                        if(url.contains("login")){
                            url = "/dashboard";
                        }
                        view = "redirect:" + url;
                    }
                }
                logger.debug("login success view: {}", view);
                result.param = TokenUtils.generate(token);
                result.status = 1;
            }
        } catch (IncorrectCredentialsException e) {
            msg = "登录密码错误. Password for account " + token.getPrincipal() + " was incorrect.";
        } catch (ExcessiveAttemptsException e) {
            msg = "登录失败次数过多";
        } catch (LockedAccountException e) {
            msg = "帐号已被锁定. The account for username " + token.getPrincipal() + " was locked.";
        } catch (DisabledAccountException e) {
            msg = "帐号已被禁用. The account for username " + token.getPrincipal() + " was disabled.";
        } catch (ExpiredCredentialsException e) {
            msg = "帐号已过期. the account for username " + token.getPrincipal() + "  was expired.";
        } catch (UnknownAccountException e) {
            msg = "帐号不存在. There is no user with username of " + token.getPrincipal();
        } catch (UnauthorizedException e) {
            msg = "您没有得到相应的授权！" + e.getMessage();
        }
        if(StringUtils.isNotEmpty(msg)) {
            logger.info(msg);
            result.newError(msg);
        }
        return result;
    }

    //@RequestMapping(value = "logout", method = RequestMethod.GET)
    public void logout() {
        Subject subject = SecurityUtils.getSubject();
        if (subject.isAuthenticated()) {

            subject.logout(); // session 会销毁，在SessionListener监听session销毁，清理权限缓存
            logger.debug("{}用户退出登录", subject.getPrincipal());
        }
    }

}
